﻿

#ifndef HPL_NODE_H
#define HPL_NODE_H

#include <vector>

namespace hpl
{

/** From which all parsing statements are inherited.*/
class Node
{
public:
	
	Node(const int type, Node* parent);
	
	/** Removes all children.*/
	virtual ~Node();
	
	/** All possible types. Used to cast common "Node" type to any other. Associations between these types and classes must be pretty clear.*/
	enum
	{
		PROGRAM,	/**< Whole processing program - parsing entry point - handles source files one-by-one.*/
		FILE,	/**< Lexical starting point - expects classes/functions/variables/macros declarations and so on.*/
		NAMESPACE,	/**< "namespace" as in C++.*/
		FUNCTION_DECLARATION,	/**< "int SomeFunction();" - without curly braces (body).*/
		FUNCTION_BODY,	/**< "int SomeFunction() { ... }".*/
		FUNCTION_CALL,	/**< "SomeFunction();".*/
		VARIABLE_DECLARATION,	/**< "int x;".*/
		VARIABLE_MODIFICATION,	/**< Such as "x = 5 + 3;" or "x -= 2;".*/
		EXPRESSION,	/**< Any mathematical expression such as "5 + 3".*/
		CLASS_DECLARATION,	/**< "class SomeClass;" - without curly braces (body).*/
		CLASS_BODY,	/**< "class SomeClass { ... };".*/
		CONSTANT,	/**< "const int x = 0;".*/
		TEXT,	/**< Literal string: "some text".*/
		SOURCE_TEXT,	/**< Some text within source code which is kept for translation.*/
		WHILE_CYCLE,
		DO_WHILE_CYCLE,
		FOR_CYCLE,
		COMMENT,
		SPACE,
		NEW_LINE,
		MACRO,	/**< #define ... */
		HPL_PP,	/**< Preprocessor directive associated only with HPL itself. Starts with "#hpl ...".*/
	};
	
	unsigned char GetType() const;
	
	/** Returns node's parent. Returns NULL if node is of type Node::PROGRAM .*/
	Node* GetParent();
	
	size_t GetChildrenCount();
	/** Returns NULL if there is no children under such index.*/
	Node* GetChild(const size_t index);
	void AddChild(Node* node);
	
	/** Step parsing with another token.*/
	virtual void Step(const char token) = 0;
	/** Must return true if last passed token ended lexical structure.*/
	virtual bool WasFilled() const;
	/** Returns true if last call to Step() did not used passed token - so that one have to be used for subsecent parent's parsing.*/
	virtual bool TokenAbandoned() const;
	
private:
	
	unsigned char type;
	
	Node* parent;
	
	std::vector<Node*> children;
	
	bool wasFilled;
	bool tokenAbandoned;
};

#endif//#ifndef HPL_NODE_H

